﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UvsChess;

namespace StudentAI.BitBoard
{

    #region Enums

    #region ChessPieceColor enum

    #endregion

    #region ChessPieceType enum

    public enum ChessPieceType
    {
        King,
        Queen,
        Rook,
        Bishop,
        Knight,
        Pawn,
        None
    }

    #endregion

    #endregion

    public sealed class Piece
    {       
        #region InternalMembers

        internal ChessColor PieceColor;
        internal ChessPieceType PieceType;

        internal short PieceValue;
        internal short PieceActionValue;

        internal short AttackedValue;
        internal short DefendedValue;

        internal int LastValidMoveCount;
        internal bool Moved;

        internal bool Selected;

        internal Stack<byte> ValidMoves;

        #endregion

        #region Constructors

        internal Piece(ChessPiece piece)
        {
            #region convert piece
            switch (piece)
            {
                case ChessPiece.BlackBishop: 
                    PieceType = ChessPieceType.Bishop;
                    PieceColor = ChessColor.Black;
                    break;
                case ChessPiece.BlackKing:
                    PieceType = ChessPieceType.King;
                    PieceColor = ChessColor.Black;
                    break;
                case ChessPiece.BlackKnight:
                    PieceType = ChessPieceType.Knight;
                    PieceColor = ChessColor.Black;
                    break;
                case ChessPiece.BlackPawn:
                    PieceType = ChessPieceType.Pawn;
                    PieceColor = ChessColor.Black;
                    break;
                case ChessPiece.BlackQueen:
                    PieceType = ChessPieceType.Queen;
                    PieceColor = ChessColor.Black;
                    break;
                case ChessPiece.BlackRook:
                    PieceType = ChessPieceType.Rook;
                    PieceColor = ChessColor.Black;
                    break;
                case ChessPiece.WhiteKing:
                    PieceType = ChessPieceType.King;
                    PieceColor = ChessColor.White;
                    break;
                case ChessPiece.WhiteKnight:
                    PieceType = ChessPieceType.Knight;
                    PieceColor = ChessColor.White;
                    break;
                case ChessPiece.WhitePawn:
                    PieceType = ChessPieceType.Pawn;
                    PieceColor = ChessColor.White;
                    break;
                case ChessPiece.WhiteQueen:
                    PieceType = ChessPieceType.Queen;
                    PieceColor = ChessColor.White;
                    break;
                case ChessPiece.WhiteRook:
                    PieceType = ChessPieceType.Rook;
                    PieceColor = ChessColor.White;
                    break;
                case ChessPiece.WhiteBishop:
                    PieceType = ChessPieceType.Bishop;
                    PieceColor = ChessColor.White;
                    break;
            }
            #endregion
            if (PieceType == ChessPieceType.Pawn || PieceType == ChessPieceType.Knight)
            {
                LastValidMoveCount = 2;
            }
            else
            {
                LastValidMoveCount = 0;
            }

            ValidMoves = new Stack<byte>(LastValidMoveCount);
            PieceValue = CalculatePieceValue(PieceType);
            PieceActionValue = CalculatePieceActionValue(PieceType);
        }

        internal Piece(Piece piece)
        {
            PieceColor = piece.PieceColor;
            PieceType = piece.PieceType;
            Moved = piece.Moved;
            PieceValue = piece.PieceValue;
            PieceActionValue = piece.PieceActionValue;

            if (piece.ValidMoves != null)
                LastValidMoveCount = piece.ValidMoves.Count;
        }

        internal Piece(ChessPieceType chessPiece, ChessColor chessPieceColor)
        {
            PieceType = chessPiece;
            PieceColor = chessPieceColor;

            if (PieceType == ChessPieceType.Pawn || PieceType == ChessPieceType.Knight)
            {
                LastValidMoveCount = 2;
            }
            else
            {
                LastValidMoveCount = 0;
            }

            ValidMoves = new Stack<byte>(LastValidMoveCount);

            PieceValue = CalculatePieceValue(PieceType);
            PieceActionValue = CalculatePieceActionValue(PieceType);
        }

        #endregion


        #region InternalMembers

        internal static string GetPieceTypeShort(ChessPieceType pieceType)
        {
            switch (pieceType)
            {
                case ChessPieceType.Pawn:
                    {
                        return "P";
                    }
                case ChessPieceType.Knight:
                    {
                        return "N";
                    }
                case ChessPieceType.Bishop:
                    {
                        return "B";
                    }
                case ChessPieceType.Rook:
                    {
                        return "R";
                    }

                case ChessPieceType.Queen:
                    {
                        return "Q";
                    }

                case ChessPieceType.King:
                    {
                        return "K";
                    }
                default:
                    {
                        return "P";
                    }
            }
        }

        #endregion

        #region PrivateMethods

        private static short CalculatePieceValue(ChessPieceType pieceType)
        {
            switch (pieceType)
            {
                case ChessPieceType.Pawn:
                    {
                        return 100;

                    }
                case ChessPieceType.Knight:
                    {
                        return 320;
                    }
                case ChessPieceType.Bishop:
                    {
                        return 325;
                    }
                case ChessPieceType.Rook:
                    {
                        return 500;
                    }

                case ChessPieceType.Queen:
                    {
                        return 975;
                    }

                case ChessPieceType.King:
                    {
                        return 32767;
                    }
                default:
                    {
                        return 0;
                    }
            }
        }


        private static short CalculatePieceActionValue(ChessPieceType pieceType)
        {
            switch (pieceType)
            {
                case ChessPieceType.Pawn:
                    {
                        return 6;

                    }
                case ChessPieceType.Knight:
                    {
                        return 3;
                    }
                case ChessPieceType.Bishop:
                    {
                        return 3;
                    }
                case ChessPieceType.Rook:
                    {
                        return 2;
                    }

                case ChessPieceType.Queen:
                    {
                        return 1;
                    }

                case ChessPieceType.King:
                    {
                        return 1;
                    }
                default:
                    {
                        return 0;
                    }
            }
        }

        #endregion
    }
}
